package com.fox.oauthfirst.authserver.service;

import com.fox.oauthfirst.authserver.model.OAuthClients;
import com.fox.oauthfirst.authserver.repository.OAuthClientRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
class MyClientDetailsService implements ClientDetailsService {

    @Autowired
    OAuthClientRepository clientRepository;

    @Override
    public ClientDetails loadClientByClientId(String s) throws ClientRegistrationException {
        log.info("ss:" + s);
        OAuthClients oac = clientRepository.findByClientId(s);
        if (oac == null) {
            throw new ClientRegistrationException("Client Not Exists:" + s);
        }
        return new ClientDetails() {
            @Override
            public String getClientId() {
                return oac.getClientId();
            }

            @Override
            public Set<String> getResourceIds() {
                return Arrays.stream(oac.getResourceIds().split(",")).collect(Collectors.toSet());
            }

            @Override
            public boolean isSecretRequired() {
                return true;
            }

            @Override
            public String getClientSecret() {
                return oac.getClientSecret();
            }

            @Override
            public boolean isScoped() {
                return true;
            }

            @Override
            public Set<String> getScope() {
                return Arrays.stream(oac.getScope().split(",")).collect(Collectors.toSet());
            }

            @Override
            public Set<String> getAuthorizedGrantTypes() {
                return Arrays.stream(oac.getAuthorizedGrantTypes().split(",")).collect(Collectors.toSet());
            }

            @Override
            public Set<String> getRegisteredRedirectUri() {
                String uri = oac.getWebServerRedirectUri();
                Set<String> result = new HashSet<>();
                result.add(uri);
                return result;
            }

            @Override
            public Collection<GrantedAuthority> getAuthorities() {

                return Arrays.stream(oac.getAuthorities().split(","))
                        .map(str -> new SimpleGrantedAuthority(str)).collect(Collectors.toList());
            }

            @Override
            public Integer getAccessTokenValiditySeconds() {
                return oac.getAccessTokenValidity() * 60;
            }

            @Override
            public Integer getRefreshTokenValiditySeconds() {
                return oac.getRefreshTokenValidity();
            }

            @Override
            public boolean isAutoApprove(String s) {
                return "true".equals(oac.getAutoapprove());
            }

            @Override
            public Map<String, Object> getAdditionalInformation() {
                Map<String, Object> result = new HashMap<>();
                result.put("more", oac.getAdditionalInformation());
                return result;
            }
        };
    }

}
